﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoodTrader.GTDownload
{
    public class CpSvrNew7221Downloader : CpDownLoader
    {
        private double[] arrVal = new double[GTGlobal.MaxDownloadCount];

        private CPSYSDIBLib.CpSvrNew7221Class m_CpSvrNew7221Fetcher = new CPSYSDIBLib.CpSvrNew7221Class();
        public CpSvrNew7221Downloader(CpDownLoadManager aDownManager)
            : base(aDownManager)
        {
            m_CpSvrNew7221Fetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived);
        }

        public CpSvrNew7221Downloader(CpDownLoadManager aDownManager, CpSvrNew7221Data aData)
            : base(aDownManager)
        {
            mData = aData;
            m_CpSvrNew7221Fetcher.Received += new CPSYSDIBLib._ISysDibEvents_ReceivedEventHandler(OnReceived);
        }

        private CpSvrNew7221Data mData = new CpSvrNew7221Data();
        public CpSvrNew7221Data Data
        {
            get { return mData; }
            set { mData = value; }
        }

        private double mEndTime = 0.0;
        public double EndTime
        {
            get { return mEndTime; }
            set { mEndTime = value; }
        }

        private double mOldTime = 0.0;
        // 다운로드 함수로 상속 클래스의 함수를 재정의 한다.
        public override void Download()
        {
            // 이미 다운 받은 상태이므로 먼저 베이스 클래스의 함수를 실행한다.
            base.Download();
            // 여기서 다운로드 할 내용을 실행한다.
            //System.Windows.Forms.MessageBox.Show("FutOptDownStarted");

            object code = m_CpFutureCode.GetData(0, 0);
            // 옵션, 선물 금액으로 설정
            m_CpSvrNew7221Fetcher.SetInputValue(0, '3');
            try
            {
                // 데이터 수신 요청을 한다.
                m_CpSvrNew7221Fetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private double mDivVal = 100.0;
        public override void OnReceived()
        {
            // 베이스 클래스의 함수를 먼저 호출한다. 여기서 이벤트가 다시 설정된다. 
            base.OnReceived();

            if (mData == null)
                return;

            int tTime = Convert.ToInt32(m_CpSvrNew7221Fetcher.GetHeaderValue(0)); // 시각
            string strTime = tTime.ToString();
            string hmTime = "";
            if (strTime.Length >= 5)
            {
                hmTime = strTime.Substring(0, strTime.Length - 2);
            }
            else
            {
                hmTime = strTime;
            }

            mEndTime = Convert.ToInt32(hmTime);

            if (GTGlobal.mEndDate == 0.0 || mEndTime == 0.0 || mEndTime > GTGlobal.EndTime)
                return;

            double curTime = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetHeaderValue(0)); // 시각
            double curKPPerson = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(2, 0)) / mDivVal; // 코스피 개인 순매수
            double curKPForeign = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(5, 0)) / mDivVal; // 코스피 외국인 순매수
            double curKPOrgan = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(8, 0)) / mDivVal; // 코스피 기관계 순매수
            double curKPTrust = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(17, 0)) / mDivVal; // 코스피 투신 순매수
            double curKPPension = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(26, 0)) / mDivVal; // 코스피 기금 순매수
            double curKPNation = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(29, 0)) / mDivVal; // 코스피 국가 순매수
            double curFTPerson = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(2, 2)) / mDivVal; // 선물 개인 순매수
            double curFTForeign = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(5, 2)) / mDivVal; // 선물 외국인 순매수
            double curFTOrgan = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(8, 2)) / mDivVal; // 선물 기관계 순매수
            double curOTPersonCall = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(2, 3)) / mDivVal; // 옵션 개인 콜
            double curOTForeignCall = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(5, 3)) / mDivVal; // 옵션 외국인 콜
            double curOTOrganCall = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(8, 3)) / mDivVal; // 옵션 기관 콜
            double curOTPersonPut = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(2, 4)) / mDivVal; // 옵션 개인 풋
            double curOTForeignPut = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(5, 4)) / mDivVal; // 옵션 외국인 풋
            double curOTOrganPut = Convert.ToDouble(m_CpSvrNew7221Fetcher.GetDataValue(8, 4)) / mDivVal; // 옵션 기관계 풋
            //Console.WriteLine("7221" + mOldTime.ToString() + "::" + mEndTime.ToString());
            // 시간이 같으면 맨 마지막 요소만 값을 갱신해 준다.
            if (mEndTime == mOldTime)
            {
                int endIndex = mData.Time.Length - 1;
                mData.Time[endIndex] = curTime;
                mData.KPPerson[endIndex] = curKPPerson;
                mData.KPForeign[endIndex] = curKPForeign;
                mData.KPOrgan[endIndex] = curKPOrgan;
                mData.KPTrust[endIndex] = curKPTrust;
                mData.KPPension[endIndex] = curKPPension;
                mData.KPNation[endIndex] = curKPNation;
                mData.FTPerson[endIndex] = curFTPerson;
                mData.FTForeign[endIndex] = curFTForeign;
                mData.FTOrgan[endIndex] = curFTOrgan;
                mData.OTPersonCall[endIndex] = curOTPersonCall;
                mData.OTForeignCall[endIndex] = curOTForeignCall;
                mData.OTOrganCall[endIndex] = curOTOrganCall;
                mData.OTPersonPut[endIndex] = curOTPersonPut;
                mData.OTForeignPut[endIndex] = curOTForeignPut;
                mData.OTOrganPut[endIndex] = curOTOrganPut;
            }
            else
            {
                int cYear = 0, cMonth = 0, cDay = 0;
                GTGlobal.StockDateToSysDate(GTGlobal.mEndDate, ref cYear, ref cMonth, ref cDay);
                int cHour = 0, cMin = 0, cSec = 0;
                GTGlobal.StockTimeToSysTime(mEndTime, ref cHour, ref cMin, ref cSec);
                DateTime curDate = new DateTime(cYear, cMonth, cDay, cHour, cMin, cSec);
                // 최종적으로 받은 시간을 확인해 1분씩 작은 값들을 모두 할당해 준다.
                for (int i = GTGlobal.MaxDownloadCount - 1, j = 0; i > -1; i--, j++)
                {
                    mData.SysTime[i] = curDate.AddMinutes(-j);
                }

                GTGlobal.ShiftArrayVal(curTime, mData.Time, arrVal);
                GTGlobal.ShiftArrayVal(curKPPerson, mData.KPPerson, arrVal);
                GTGlobal.ShiftArrayVal(curKPForeign, mData.KPForeign, arrVal);
                GTGlobal.ShiftArrayVal(curKPOrgan, mData.KPOrgan, arrVal);
                GTGlobal.ShiftArrayVal(curKPTrust, mData.KPTrust, arrVal);
                GTGlobal.ShiftArrayVal(curKPPension, mData.KPPension, arrVal);
                GTGlobal.ShiftArrayVal(curKPNation, mData.KPNation, arrVal);
                GTGlobal.ShiftArrayVal(curFTPerson, mData.FTPerson, arrVal);
                GTGlobal.ShiftArrayVal(curFTForeign, mData.FTForeign, arrVal);
                GTGlobal.ShiftArrayVal(curFTOrgan, mData.FTOrgan, arrVal);
                GTGlobal.ShiftArrayVal(curOTPersonCall, mData.OTPersonCall, arrVal);
                GTGlobal.ShiftArrayVal(curOTForeignCall, mData.OTForeignCall, arrVal);
                GTGlobal.ShiftArrayVal(curOTOrganCall, mData.OTOrganCall, arrVal);
                GTGlobal.ShiftArrayVal(curOTPersonPut, mData.OTPersonPut, arrVal);
                GTGlobal.ShiftArrayVal(curOTForeignPut, mData.OTForeignPut, arrVal);
                GTGlobal.ShiftArrayVal(curOTOrganPut, mData.OTOrganPut, arrVal);
            }
            mOldTime = mEndTime;
        }
    }
}
